﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Divelements.SandRibbon;
using Hydra.Shell.Interfaces;
using Hydra.Shell.Attributes;
using Hydra.Shell.Implementations;
using Hydra.Shell.Constants;
using EnvDTE = Hydra.Shell.Interfaces.EnvDTE;
using System.Diagnostics;
using System.Windows.Browser;

namespace Hydra.Shell.Controls
{
    public partial class HydraCommandBar : UserControl, IObjectWithSite, IUnknown
    {
        private IHydraShell hydraShell;
        private IHydraUIShell hydraUIShell;
        private IQueryServiceProvider serviceProvider;
        private EnvDTE.DTE dte;
        private IUnknown site;

        public HydraCommandBar()
        {
            InitializeComponent();
        }

        public string ApplicationName
        {
            get
            {
                return RibbonBar.ApplicationName;
            }

            set
            {
                RibbonBar.ApplicationName = value;
            }
        }

        public string Title
        {
            get
            {
                return RibbonBar.Title;
            }

            set
            {
                RibbonBar.Title = value;
            }
        }

        private void Ribbon_LivePreview(object sender, LivePreviewEventArgs e)
        {
            //if (e.Control == this.colorPickerFontColor)
            //{
            //    Color parameter = (Color)e.Parameter;
            //    e.PreviewObject = new BackgroundColorPreview(this.livePreviewBackground, parameter);
            //}
            //if (e.Control == this.comboFontSize)
            //{
            //    Divelements.SandRibbon.ComboBoxItem item = (Divelements.SandRibbon.ComboBoxItem)e.Parameter;
            //    int newFontSize = int.Parse((string)item.Content());
            //    e.PreviewObject = new FontSizePreview(this.livePreviewTextBlock, newFontSize);
            //}
        }

        private void colorPickerFontColor_ColorPicked(object sender, ColorEventArgs e)
        {
            //this.livePreviewBackground.Background(new SolidColorBrush(e.Color));
        }

        private void RibbonGroup_LaunchDialog(object sender, EventArgs e)
        {
            MessageBox.Show("Clicking a dialog launcher would normally launch a Silverlight ChildWindow or a SandDock Window." + Environment.NewLine + Environment.NewLine + "The user then has a chance to perform some modal actions that offer additional flexibility to the tools in the ribbon group.");
        }

        private class BackgroundColorPreview : ILivePreview
        {
            private Border border;
            private Color color;
            private Brush oldBackgroundBrush;

            public BackgroundColorPreview(Border border, Color color)
            {
                this.border = border;
                this.color = color;
            }

            public void ActivatePreview()
            {
                //this.oldBackgroundBrush = this.border.Background();
                //this.border.Background(new SolidColorBrush(this.color));
            }

            public void RemovePreview()
            {
                //this.border.Background(this.oldBackgroundBrush);
            }
        }

        private class FontSizePreview : ILivePreview
        {
            private double newFontSize;
            private double oldFontSize;
            private TextBlock textBlock;

            public FontSizePreview(TextBlock textBlock, int newFontSize)
            {
                this.textBlock = textBlock;
                this.newFontSize = newFontSize;
            }

            public void ActivatePreview()
            {
                //this.oldFontSize = this.textBlock.FontSize();
                //this.textBlock.FontSize(this.newFontSize);
            }

            public void RemovePreview()
            {
                //this.textBlock.FontSize(this.oldFontSize);
            }
        }

        private void RibbonTabAbout_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //dte.Commands.Raise(
        }

        public void SetSite(IUnknown pUnkSite)
        {
            ServiceLoadOperation<EnvDTE.DTE> loadOp;

            site = pUnkSite;

            Debug.Assert(site.QueryInterface<IHydraShell>(out hydraShell));
            Debug.Assert(site.QueryInterface<IQueryServiceProvider>(out serviceProvider));

            if (serviceProvider.QueryService<EnvDTE.DTE>(typeof(EnvDTE.DTE).GetGuid(), out loadOp))
            {
                loadOp.ServiceLoaded += (sender2, e2) =>
                {
                    dte = loadOp.Service;
                };

                loadOp.ExceptionOccured += (sender2, e2) =>
                {
                    Debugger.Break();
                };
            }
        }

        public bool GetSite(Guid riid, out IUnknown ppvSite)
        {
            return site.QueryInterface(riid, out ppvSite);
        }

        public bool GetSite<T>(Guid riid, out T ppvSite)
        {
            IUnknown pUnk;

            if (site.QueryInterface(riid, out pUnk))
            {
                ppvSite = (T)pUnk;
                return true;
            }
            else
            {
                ppvSite = default(T);
                return false;
            }
        }

        public bool IsDisposed
        {
            get 
            {
                return false;
            }
        }

        public bool QueryInterface(Guid iid, out IUnknown interfaceObject)
        {
            var isInterface = this.GetType().GetInterfaces().Any(i => i.GUID == iid || i.GetCustomAttributes(true).Any(a => a is GuidAttribute && ((GuidAttribute)a).Value == iid.ToString()));

            if (isInterface)
            {
                interfaceObject = this;
                return true;
            }
            else
            {
                interfaceObject = new CommonException(HydraConstants.E_NOINTERFACE);
                return false;
            }
        }

        public bool QueryInterface<T>(out T interfaceObject)
        {
            var iid = typeof(T).GetGuid();
            var isInterface = this.GetType().GetInterfaces().Any(i =>
            {
                return i.GUID == iid || i.GetCustomAttributes(true).Any(a =>
                {
                    return a is GuidAttribute && ((GuidAttribute)a).Value.ToLower() == iid.ToString().ToLower();
                });
            });

            if (isInterface)
            {
                interfaceObject = (T)(object)this;
                return true;
            }
            else
            {
                interfaceObject = (T)(object)new CommonException(HydraConstants.E_NOINTERFACE);
                return false;
            }
        }

        private void Page_Refresh(object sender, ActivateEventArgs e)
        {
            HtmlPage.Window.Navigate(HtmlPage.Document.DocumentUri);
        }

        private void Diagnostics_ViewPackageMonitor(object sender, ActivateEventArgs e)
        {
            HtmlPage.Window.Navigate(new Uri("PackageMonitor.aspx", UriKind.Relative), "new");
        }
    }
}
